package com.wing.sell.controller.admin;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wing.common.utils.Result;
import com.wing.platform.feign.PlatformClient;
import com.wing.product.model.entity.ProductDetail;
import com.wing.product.model.entity.ProductType;
import com.wing.product.model.entity.ProductUnitInfo;
import com.wing.product.model.response.ProductTypeVO;
import com.wing.product.service.ProductDetailService;
import com.wing.product.service.ProductTypeService;
import com.wing.product.service.ProductUnitService;
import com.wing.sell.model.entity.*;
import com.wing.sell.model.response.*;
import com.wing.sell.service.*;
import com.wing.web.annotation.RequestObjectFieldIgnore;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.PageResult;
import com.wing.sell.model.request.OrderForm;
import com.wing.web.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author
 */
@Validated
@Api(value = "Admin-询价销售订单表管理", tags = "#/sell/order")
@RestController("orderController")
@RequestMapping("sell/admin/order")
@RequiredArgsConstructor
@Slf4j
public class OrderController {

    private final OrderService orderService;
    private final OrderProService orderProService;
    private final CustomersInfoService customersInfoService;
    private final ContactInfoService contactInfoService;
    private final AgentService agentService;
    private final OrderProReviewService orderProReviewService;
    private final OrderProEnclosureService orderProEnclosureService;
    private final OrderOfferService orderOfferService;
    private final OrderOfferDetailService orderOfferDetailService;
    private final OrderReviewProcessService orderReviewProcessService;
    private final ProductUnitService productUnitService;
    private final ProductTypeService productTypeService;
    private final PlatformClient platformClient;
    private final ProductDetailService productDetailService;

    @ApiOperation(value = "查询所有销售订单表", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", example = "1", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", example = "10", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "sort", value = "排序字段名", defaultValue = "create_time", example = "create_time", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "order", value = "排序规则(asc:正序, desc:倒序)", defaultValue = "desc", example = "asc", dataType = "String", paramType = "query")
    })
    @GetMapping("/list")
    public PageResult<OrderVO> list(
            @RequestParam(defaultValue = "1") Integer page
            , @RequestParam(defaultValue = "10") Integer limit
            , @RequestParam(defaultValue = "create_time") String sort
            , @RequestParam(defaultValue = "desc") String order
            , String code
            , Order.Status status
            , Long customerId
            , Order.OrderSource orderSource
            , Order.OrderType orderType
            , String customerName
    ) {

        Page<OrderVO> pg = new Page<>(page, limit);

        //排序
        Map params = new HashMap();
        params.put("sort", StrUtil.toUnderlineCase(sort));
        params.put("order", StrUtil.toUnderlineCase(order));

        if (null != customerId){
            params.put("customerId",customerId);
        }

        //搜索
        if (StringUtils.isNotBlank(code)) {
            params.put("code", code);
        }
        if (status != null) {
            params.put("status", status.getValue());
        }
        if (orderSource != null) {
            params.put("orderSource", orderSource.getValue());
        }
        if (StringUtils.isNotBlank(customerName)) {
            List<CustomersInfo> customersInfoList = customersInfoService.list(new QueryWrapper<CustomersInfo>().like("customer_name", customerName));
            if (customersInfoList.size() > 0) {
                List listIds = new ArrayList();
                for (int i = 0; i < customersInfoList.size(); i++) {
                    listIds.add(customersInfoList.get(i).getId());
                }
                params.put("listIds", listIds);
            } else {
                params.put("customerId", "");
            }

        }
        if (orderType != null) {
            params.put("orderType", orderType.getValue());
        } else {
            params.put("show", new ArrayList<Integer>() {{
                add(0);
                add(1);
                add(2);
                add(3);
                add(4);
                add(5);
                add(6);
                add(8);
            }});
        }

        IPage<OrderVO> list = orderService.pageList4app(pg, params);
        list.getRecords().parallelStream().forEach(k -> {
            //客户公司名称
            CustomersInfoVO appById = customersInfoService.get4appById(k.getCustomerId());
            if (ObjectUtil.isNotEmpty(appById)) {
                k.setCustomerName(appById.getCustomerName());
            }
            //联系人名称
            ContactInfoVO appById1 = contactInfoService.get4appById(k.getCustomerContactsId());
            if (ObjectUtil.isNotEmpty(appById1)) {
                k.setCustomerContactsName(appById1.getName());
                k.setCustomerContactsPhone(appById1.getTelephone());
            }

            //渠道名称
            if (k.getChannelId() == null) {//非渠道订单 渠道ID为空
                k.setChannelName("非渠道订单");
            } else {
                AgentVO agent = agentService.get4appById(k.getChannelId());
                if (ObjectUtil.isNotEmpty(agent)) {
                    k.setChannelName(agent.getName());
                }
            }
        });
        return new PageResult<>(list.getRecords(), list.getTotal());
    }


    /**
     * 查询订单详情
     *
     * @param id
     * @return
     */
    @GetMapping("/detail/{id}")
    public JsonResult getDetailById(@PathVariable("id") Long id) {
        OrderVO orderVO = orderService.getDetailById(id);
        //包含产品  关联评审记录 关联附件
        QueryWrapper<OrderPro> proQueryWrapper = new QueryWrapper<>();
        proQueryWrapper.eq("order_id", orderVO.getId());

        //查询渠道名称
        if (null != orderVO.getChannelId()){
            Agent byId = agentService.getById(orderVO.getChannelId());
            if (ObjectUtil.isNotEmpty(byId)) {
                orderVO.setChannelName(byId.getName());
            }
        }

        Map<Long, String> units = productUnitService.
                list().stream()
                .filter(unitInfo -> unitInfo.getId() != null && !unitInfo.getName().isEmpty())
                .collect(Collectors.toMap(ProductUnitInfo::getId, ProductUnitInfo::getName, (existing, replacement) -> replacement));
        Map<Long, String> types = productTypeService.
                list().stream()
                .filter(type -> type.getId() != null && !type.getName().isEmpty())
                .collect(Collectors.toMap(ProductType::getId, ProductType::getName, (existing, replacement) -> replacement));

        if (orderVO.getStatus().equals(Order.Status.offer)) {
            //只评审 受理的产品
            if (orderVO.getStatus() == Order.Status.review) {
                proQueryWrapper.eq("status", OrderPro.Status.accepted);
            }
        }
        //只报价 终审通过的产品 后续展示也是
        if (orderVO.getStatus() == Order.Status.offer || orderVO.getStatus() == Order.Status.tosign || orderVO.getStatus() == Order.Status.signed || orderVO.getStatus() == Order.Status.finish) {
            proQueryWrapper.eq("final_result", OrderPro.FinalResult.pass);
        }
        List<OrderPro> proList = orderProService.list(proQueryWrapper);
        List<Long> collect = proList.stream()
                .map(OrderPro::getProductDetailId)
                .filter(productDetailId -> ObjectUtil.isNotNull(productDetailId)).collect(Collectors.toList());
        Map<String,Object> map = new HashMap<>();
        map.put("ids",collect);
        List<ProductDetail> productDetails = productDetailService.list4app(map);

        //产品列表
        Map<Long, ProductDetail> details = productDetails.stream()
                .filter(detail -> detail.getId() != null && !detail.getSkuCode().isEmpty())
                .collect(Collectors.toMap(ProductDetail::getId, productDetail -> productDetail));
        proList.forEach(z -> {

            BigDecimal bigDecimal = orderOfferService.getOffMoneyBy(z.getOrderId(),z.getId());
            z.setOfferMoney(bigDecimal);
            if (null != z.getProUnitId()){
                z.setProUnitName(units.get(z.getProUnitId()));
            }
            if (null != z.getProductDetailId()){
                ProductDetail productDetail = details.get(z.getProductDetailId());
                if (ObjectUtil.isNotEmpty(productDetail)) {
                    z.setSkuCode(productDetail.getSkuCode());
                    z.setSkuName(productDetail.getSkuName());
                    z.setWeight(productDetail.getWeight());
                }
            }
            if (null != z.getProTypeId()){
                z.setProTypeName(types.get(z.getProTypeId()));
            }
            //产品关联评审记录
            QueryWrapper<OrderProReview> wrapper = new QueryWrapper<>();
            wrapper.eq("pro_id", z.getCusProductId());
            wrapper.eq("order_id",z.getOrderId());
            List<OrderProReview> orderProReviewList = orderProReviewService.list(wrapper);
            orderProReviewList.parallelStream().forEach(h -> {
                OrderReviewProcessVO appById = orderReviewProcessService.get4appById(h.getReviewProcessId());
                if (ObjectUtil.isNotEmpty(appById)) {
                    h.setReviewProcessName(appById.getName());
                }
            });
            z.setOrderProReviewList(orderProReviewList);
            //产品关联附件
            QueryWrapper<OrderProEnclosure> query = new QueryWrapper<>();
            query.eq("pro_id", z.getCusProductId());
            query.eq("order_id", z.getOrderId());
            z.setOrderProEnclosureList(orderProEnclosureService.list(query));
        });
        //包含产品
        orderVO.setOrderProList(proList);

        return JsonResult.success(orderVO);
    }


    /**
     * 查询客户订单
     *
     * @return
     */
    @ApiOperation(value = "查询客户的订单", notes = "搜索-客户订单")
    @GetMapping("/allOrderListByCustomer")
    public JsonResult getOrderListByCustomer(@RequestParam("customerId") Long customerId,
                                             @RequestParam(value = "types", required = false) List<String> types) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("customer_id", customerId);
        queryWrapper.orderByDesc("create_time");
        if (!CollectionUtils.isEmpty(types)) {
            queryWrapper.in("order_type", types);
        }
        List<Order> list = orderService.list(queryWrapper);
        return JsonResult.success(list);
    }

    @ApiOperation(value = "查询所有销售订单表", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", example = "1", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", example = "10", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "sort", value = "排序字段名", defaultValue = "create_time", example = "create_time", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "order", value = "排序规则(asc:正序, desc:倒序)", defaultValue = "desc", example = "asc", dataType = "String", paramType = "query")
    })
    @GetMapping("/getOrderPageList")
    public PageResult<OrderVO> getOrderPageList(
            @RequestParam(defaultValue = "1") Integer page
            , @RequestParam(defaultValue = "10") Integer limit
            , @RequestParam(defaultValue = "create_time") String sort
            , @RequestParam(defaultValue = "desc") String order
            , String code
            , Integer whetherList
            , Order.Status status
            , Order.OrderSource orderSource
            , Order.OrderType orderType
    ) {

        Page<OrderVO> pg = new Page<>(page, limit);
        //排序
        Map<String,Object> params = new HashMap();
        params.put("sort", "create_time");
        params.put("order", "desc");

        //搜索
        if (StringUtils.isNotBlank(code)) {
            params.put("code", code);
        }
        if (status != null) {
            params.put("status", status);
        }
        if (orderSource != null) {
            params.put("orderSource", orderSource);
        }
        if (orderType != null) {
            params.put("orderType", orderType);
        }
        params.put("show", new ArrayList<Integer>() {{
            add(6);
            add(7);
        }});
        IPage<OrderVO> list = orderService.pageList4app(pg, params);
        //正式订单列表才查询产品相关信息
        if (whetherList != null && whetherList == 1) {
            list.getRecords().parallelStream().forEach(k -> {
                //包含产品 关联附件
                QueryWrapper<OrderPro> proQueryWrapper = new QueryWrapper<>();
                proQueryWrapper.eq("order_id", k.getId());
                List<OrderPro> proList = orderProService.list(proQueryWrapper);
                k.setOrderProList(proList);
                proList.parallelStream().forEach(z -> {
                    //最终报价
                    QueryWrapper<OrderOffer> offerWrapper = new QueryWrapper<>();
                    offerWrapper.eq("order_id", k.getId());
                    offerWrapper.eq("whether_final", 1);
                    List<OrderOffer> orderOfferList = orderOfferService.list(offerWrapper);
                    if (CollectionUtils.isNotEmpty(orderOfferList)) {
                        orderOfferList.parallelStream().forEach(o -> {
                            QueryWrapper<OrderOfferDetail> offerDetailWrapper = new QueryWrapper<>();
                            offerDetailWrapper.eq("offer_id", o.getId());
                            offerDetailWrapper.eq("pro_id", z.getId());
                            OrderOfferDetail orderOfferDetail = orderOfferDetailService.getOne(offerDetailWrapper);
                            if (orderOfferDetail != null) {
                                z.setOfferMoney(orderOfferDetail.getOfferMoney());
                            }

                        });
                    }
                    //产品关联附件
                    QueryWrapper<OrderProEnclosure> query = new QueryWrapper<>();
                    z.setOrderProEnclosureList(orderProEnclosureService.list(query.eq("pro_id", z.getId())));
                    ProductTypeVO productTypeVO = productTypeService.get4appById(z.getProTypeId());
                    if (productTypeVO != null) {
                        z.setProTypeName(productTypeVO.getName());
                    }
                    //订单产品创建生产计划后的剩余需求数量
                    Integer orderProResidueQuantity = orderProService.getOrderProResidueQuantity(z.getId());
                    z.setResidueQuantity(z.getQuantity() - orderProResidueQuantity);
                });
            });
        }


        return new PageResult<>(list.getRecords(), list.getTotal());
    }

    @ApiOperation(value = "查询意向客户和正式客户", notes = "搜索")
    @GetMapping("/getCustomers")
    public JsonResult getCustomers() {
        QueryWrapper<CustomersInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("customer_type", 2, 3);
        List<CustomersInfo> list = customersInfoService.list(queryWrapper);
        return JsonResult.success("添加成功", list);
    }


    @ApiOperation(value = "查询意向客户和正式客户", notes = "搜索")
    @GetMapping("/getCustomersDetail/{id}")
    public JsonResult getCustomersDetail(@PathVariable Long id) {
        CustomersInfoSearchVo list = customersInfoService.getCustomersDetail(id);
        return JsonResult.success("添加成功", list);
    }

    @ApiOperation(value = "添加销售订单表", notes = "添加")
    @RequestObjectFieldIgnore({"id", "createTime", "remark"})
    @PostMapping("/add")
    public JsonResult add(@Validated(OrderForm.Add.class) @RequestBody OrderForm orderForm) {
        try {
            orderService.add(orderForm);
            return JsonResult.success("添加成功");
        } catch (Exception e) {
            log.error("添加失败:", e);
            return JsonResult.fail("添加失败" + e.getMessage());
        }
    }

    @ApiOperation(value = "确认提交", notes = "修改")
    @PostMapping("/submit")
    public JsonResult submit(@RequestParam("id") Long id, @RequestParam("type") Integer type) {//6 已签约  1 修改状态为1 待受理 2 修改状态为2 待评审  8修改状态为8 关闭  7修改状态为7 已完成  4修改为4待报价  3修改为3 不接单 所有产品都不接单
        try {
            orderService.submit(id, type);
            return JsonResult.success("修改成功");
        } catch (Exception e) {
            log.error("修改失败:", e);
            return JsonResult.fail("修改失败" + e.getMessage());
        }
    }


    @ApiOperation(value = "修改销售订单表", notes = "修改")
    @PutMapping("/update")
    public JsonResult update(@Validated(OrderForm.Update.class) @RequestBody OrderForm orderForm) {
        Order order = orderService.getById(orderForm.getId());
        if (order == null) {
            return JsonResult.fail("修改失败！");
        }
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(Order.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(orderForm, order, copyOptions);

        if (orderForm.getOrderProList() != null) {
            for (OrderPro orderPro : orderForm.getOrderProList()) {
                if (orderPro.getId() != null) {//修改产品
                    orderProService.updateById(orderPro);
                } else {//新增产品
                    orderPro.setOrderId(order.getId());
                    orderPro.setStatus(OrderPro.Status.pending);//刚添加为待受理状态
                    orderProService.getBaseMapper().insert(orderPro);
                }
                //只会新增附件
                for (OrderProEnclosure orderProEnclosure : orderPro.getOrderProEnclosureList()) {
                    if (orderProEnclosure.getId() == null) {
                        orderProEnclosure.setOrderId(order.getId());
                        orderProEnclosure.setProId(orderPro.getId());
                        orderProEnclosureService.getBaseMapper().insert(orderProEnclosure);
                    }
                }
            }
        }

        if (orderService.updateById(order)) {
            return JsonResult.success("修改成功！");
        }
        return JsonResult.fail("修改失败！");
    }


    @ApiOperation(value = "查询该订单可用的评审环节", notes = "查询")
    @GetMapping("/findReview")
    public JsonResult findReview(Order.OrderType type) {
        try {
            List<OrderReviewProcess> list = orderReviewProcessService.list();
            for (int j = list.size() - 1; j >= 0; j--) {
                if (!StringUtils.contains(list.get(j).getOrderTypes(), String.valueOf(type.getValue() + 1))) {
                    list.remove(j);
                }
            }
            return JsonResult.success("查询成功", list);
        } catch (Exception e) {
            return JsonResult.fail("查询失败", e.getMessage());
        }
    }


    @ApiOperation(value = "删除销售订单表", notes = "删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "销售订单表id", required = true, dataType = "Integer", paramType = "path")
    })
    @DeleteMapping("/{id}")
    public JsonResult delete(@PathVariable("id") Long orderId) {
        if (orderService.removeById(orderId)) {
            return JsonResult.success("删除成功");
        }
        return JsonResult.fail("删除失败");
    }

    @ApiOperation(value = "查询销售订单", notes = "删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "销售订单表id", required = true, dataType = "Integer", paramType = "path")
    })
    @GetMapping("/getOrderById")
    public JsonResult<OrderVO> getOrderById(@RequestParam("id") Long id, @RequestParam("skuCode") String skuCode) {
        OrderVO orderVO = orderService.get4appById(id);
        if (orderVO != null) {
            OrderPro orderPro = orderProService.getOrderProVOByOrderId(id, skuCode);
            orderVO.setDemandQuantity(orderPro.getQuantity());
        }
        return JsonResult.success(orderVO);
    }

    @ApiOperation(value = "添加智能柜采购订单", notes = "修改")
    @PostMapping("/addCabinetPurchaseOrder")
    public JsonResult addCabinetPurchaseOrder(@RequestBody com.wing.platform.order.model.request.OrderForm orderForm) {
        orderForm.setEnterpriseCode(JwtUtils.getChannelCode());
        JsonResult jsonResult = platformClient.addCabinetPurchaseOrder(orderForm);
        if (jsonResult.getCode() != Result.Code.SUCCESS.getCode()) {
            return JsonResult.fail("添加智能柜采购订单失败" + jsonResult.getMsg());
        }
        return JsonResult.success("操作成功");
    }

    @ApiOperation(value = "修改智能柜采购订单", notes = "修改")
    @PutMapping("/updateCabinetPurchaseOrder")
    public JsonResult updateCabinetPurchaseOrder(@RequestBody com.wing.platform.order.model.request.OrderForm orderForm) {
        orderForm.setEnterpriseCode(JwtUtils.getChannelCode());
        JsonResult jsonResult = platformClient.updateCabinetPurchaseOrder(orderForm);
        if (jsonResult.getCode() != Result.Code.SUCCESS.getCode()) {
            return JsonResult.fail("修改智能柜采购订单失败" + jsonResult.getMsg());
        }
        return JsonResult.success("操作成功");
    }

    @ApiOperation(value = "查询智能柜采购订单详情", notes = "搜索")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "第几页", defaultValue = "1", example = "1", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "limit", value = "每页多少条", defaultValue = "10", example = "10", dataType = "Integer", paramType = "query")
            , @ApiImplicitParam(name = "sort", value = "排序字段名", defaultValue = "create_time", example = "create_time", dataType = "String", paramType = "query")
            , @ApiImplicitParam(name = "order", value = "排序规则(asc:正序, desc:倒序)", defaultValue = "desc", example = "asc", dataType = "String", paramType = "query")
    })
    @GetMapping("/getCabinetPurchaseOrderProVOList")
    public PageResult<com.wing.platform.order.model.response.OrderProVO> getCabinetPurchaseOrderProVOList(
            @RequestParam(defaultValue = "1") Integer page
            , @RequestParam(defaultValue = "10") Integer limit
            , @RequestParam(defaultValue = "create_time") String sort
            , @RequestParam(defaultValue = "desc") String order
            , Long orderId

    ) {
        PageResult<com.wing.platform.order.model.response.OrderProVO> list = platformClient.getCabinetPurchaseOrderProVOList(page, limit, sort, order, orderId);
        return new PageResult<>(list.getData(), list.getCount());
    }


    @ApiOperation(value = "查询订单中物料信息", notes = "查询-订单sku")
    @GetMapping("/getSkuInfo/{orderId}/{warehouseId}")
    public JsonResult<List<OrderSkuDetailSearchVo>> getSkuInfo(@PathVariable("orderId")Long orderId, @PathVariable("warehouseId")Long warehouseId) {
        List<OrderSkuDetailSearchVo> list = orderService.listByInfo(orderId,warehouseId);
        list.forEach(info->{
            info.setWarehouseId(warehouseId);
        });
        return JsonResult.success(list);
    }


}
